package com.scholarship.modules.student.controller;

import com.scholarship.common.entity.RetCode;
import com.scholarship.common.entity.RetResponse;
import com.scholarship.common.entity.RetResult;
import com.scholarship.modules.admin.dto.SaveInfoDto;
import com.scholarship.modules.admin.dto.RewardTypeDetailDto;
import com.scholarship.modules.admin.dto.TableInfoDto;
import com.scholarship.modules.admin.exce.EmptyValueException;
import com.scholarship.modules.admin.service.FeedbackListService;
import com.scholarship.modules.backend.service.StuTotalScoreService;
import com.scholarship.modules.login.dto.LoginInfoDto;
import com.scholarship.modules.student.dto.*;
import com.scholarship.modules.student.dto.NApplicationDto.*;
import com.scholarship.modules.student.entity.SubmitTableItem;
import com.scholarship.modules.student.exce.*;
import com.scholarship.modules.student.service.NStuApplicationService;
import com.scholarship.modules.student.service.StudentService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.ibatis.annotations.Update;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @author: huanghao
 * @date: 2021/7/22 14:11
 * @description: 学生端2.0
 * @modifiedBy:
 */

/*
* 中文与英文对应关系
* 父类奖项：FatherReward
* 子类奖项：SonReward
* 子类奖项中的各个表项：TableItem
*/

@Api(tags = {"学生端控制层2.0"})
@RestController
public class NStudentController {
    //日志logger
    private static final Logger logger = LoggerFactory.getLogger(NStudentController.class);

    @Autowired
    private NStuApplicationService stuApplicationService;

    @Autowired
    private StudentService studentService;

    @Autowired
    private FeedbackListService feedbackListService;

    @Autowired
    StuTotalScoreService stuTotalScoreService;

    /*------------------------------奖学金申请相关功能------------------------------*/
    //获取父类+子类奖项列表
//    @ApiOperation("获取父类+子类奖项列表")
//    @PostMapping("/student2/getApplicationItems")
//    public RetResult getApplicationItems() {
//        List tmp = stuApplicationService.getApplicationItemList();
//        return RetResponse.makeRsp(RetCode.SUCCESS, "申请表奖项列表", tmp);
//    }

    //获取子类奖项结构信息
//    @ApiOperation("获取子类奖项结构信息")
//    @PostMapping("/student2/getItemStructure")
//    public RetResult getItemStructure(@RequestBody RewardInfoDto rewardInfo) {
//        RewardStructureDto rewardStructureDto = stuApplicationService.getItemStructure(rewardInfo);
//        return RetResponse.makeRsp(RetCode.SUCCESS, "子类奖项的结构信息", rewardStructureDto);
//    }

    //获取父类+子类+表项完整结构信息
    @ApiOperation("获取父类+子类+表项完整结构信息")
    @GetMapping("/student2/getApplicationTableInfo")
    public RetResult getApplicationTableInfo() {
        List<RewardTypeDto> rewardApplicationInfoDtoList = stuApplicationService.getApplicationTableInfo();
        return RetResponse.makeRsp(RetCode.SUCCESS, "学生申请表结构信息（包含父类奖项信息+子类奖项信息+各表项信息）", rewardApplicationInfoDtoList);
    }

    //保存学生奖学金申请信息
    @ApiOperation("保存学生奖学金申请信息")
    @PostMapping("/student2/saveRewardApplication")
    public RetResult saveRewardApplication(@RequestBody SaveInfoDto saveInfoDto) {
        Subject subject = SecurityUtils.getSubject();
        LoginInfoDto loginInfoDto = (LoginInfoDto)subject.getPrincipal();
        try {
//            saveInfoDto.setUserId(loginInfoDto.getUserId());
//            RewardSubmitDto rewardSubmitDto = new RewardSubmitDto();
//
//            //对SaveInfo的内容和RewardSubmitDto的内容作个转换，暂时这样写，以后改
//            rewardSubmitDto.setUserId(saveInfoDto.getUserId());
//            rewardSubmitDto.setIsUploadFile(saveInfoDto.getRewardTypeDetailDto().getIsUploadFile());
//            rewardSubmitDto.setId(saveInfoDto.getRewardTypeDetailDto().getId());
//            List<TableInfoDto> tableInfoDtoList = saveInfoDto.getRewardTypeDetailDto().getTableInfoListDto();
//            List<SubmitTableItem> submitTableItemList = new ArrayList<>();
//            for (int i = 0; i < tableInfoDtoList.size(); i++) {
//                SubmitTableItem tmpSubmitTableItem = new SubmitTableItem();
//                TableInfoDto tmpTableInfoDto = tableInfoDtoList.get(i);
//                if (tmpTableInfoDto.getIsTeacherWrite().equals(1)) {
//                    continue;
//                }
//                tmpSubmitTableItem.setAttributeName(tmpTableInfoDto.getAttributeName());
//                //下面这个转换可能有问题，待测试，因为原类型是Object
//                if (tmpTableInfoDto.getFieldId() == 2) {
//                    SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
//                    Date tmpDate = df.parse((String) tmpTableInfoDto.getValue());
//                    tmpSubmitTableItem.setValue(df.format(tmpDate));
//                }
//                else {
//                    tmpSubmitTableItem.setValue((String)tmpTableInfoDto.getValue());
//                }
//                tmpSubmitTableItem.setIsTeacherWrite(tmpTableInfoDto.getIsTeacherWrite());
//                submitTableItemList.add(tmpSubmitTableItem);
//            }
//            rewardSubmitDto.setSubmitTableItemList(submitTableItemList);
//            rewardSubmitDto.setTableName(saveInfoDto.getRewardTypeDetailDto().getTableName());
//            rewardSubmitDto.setValue(saveInfoDto.getRewardTypeDetailDto().getValue());
//            stuApplicationService.saveRewardRecord(rewardSubmitDto);
            //学生提交默认状态为审核中--3
            RewardTypeDetailDto rewardTypeDetailDto = saveInfoDto.getRewardTypeDetailDto();
            rewardTypeDetailDto.setState(3);
            rewardTypeDetailDto.setScore(0.00);
            feedbackListService.saveSelectedRewardTypeDetail(saveInfoDto.getUserId(), rewardTypeDetailDto);
        }
//        catch (ErrorException e) {
//            return RetResponse.makeRsp(RetCode.FAIL, "表单存在空值2");
//        }
        catch (EmptyValueException e) {
            logger.error("---userid: " + loginInfoDto.getUserId() + "---" + e.getMessage());
            return RetResponse.makeRsp(RetCode.FAIL, e.getMessage());
        }
        catch (Exception e) {
            e.printStackTrace();
            logger.error("---userid: " + loginInfoDto.getUserId() + "---" + e.getMessage());
            return RetResponse.makeRsp(RetCode.FAIL, "未知错误");
        }
        logger.info("---userid: " + loginInfoDto.getUserId() + "--- 保存奖学金申请信息成功");
        return RetResponse.makeRsp(RetCode.SUCCESS, "保存学生奖学金申请信息");
    }

    //提交学生奖学金申请信息
    @ApiOperation("提交学生奖学金申请信息")
    @PostMapping("/student2/submitRewardApplication2")
    public RetResult submitRewardApplication2() {
        Subject subject = SecurityUtils.getSubject();
        LoginInfoDto loginInfoDto = (LoginInfoDto)subject.getPrincipal();
        try {
            stuApplicationService.submitApplication(loginInfoDto.getUserId());
        }
        catch (UpdateSQLException e) {
//            e.printStackTrace();
            logger.error("---userid: " + loginInfoDto.getUserId() + "---" + e.getMessage());
            return RetResponse.makeRsp(RetCode.FAIL, "提交学生奖学金申请信息失败");
        }
        catch (Exception e) {
            e.printStackTrace();
            logger.error("---userid: " + loginInfoDto.getUserId() + "---" + e.getMessage());
            return RetResponse.makeRsp(RetCode.FAIL, "未知错误");
        }
        return RetResponse.makeRsp(RetCode.SUCCESS, "提交学生奖学金申请信息成功");
    }

    //获取父类+子类+表项完整结构信息 2.0
    @ApiOperation("获取父类+子类+表项完整结构信息 2.0")
    @GetMapping("/student2/getApplicationTableInfo2")
    public RetResult getApplicationTableInfo2() {
        Subject subject = SecurityUtils.getSubject();
        LoginInfoDto loginInfoDto = (LoginInfoDto)subject.getPrincipal();
        List<com.scholarship.modules.admin.dto.RewardTypeDto> rewardTypeDtoList = null;
        try {
            rewardTypeDtoList = feedbackListService.listRewardListAndInformation(loginInfoDto.getUserId());
        }
        catch (Exception e) {
            e.printStackTrace();
            logger.error("---userid: " + loginInfoDto.getUserId() + "---" + e.getMessage());
            return RetResponse.makeRsp(RetCode.FAIL, "未知错误");
        }
        return RetResponse.makeRsp(RetCode.SUCCESS, "获取学生奖学金申请信息成功", rewardTypeDtoList);
    }

    //接收前端传来的子类奖项申请信息
    @ApiOperation("接收前端传来的子类奖项申请信息")
    @PostMapping("/student2/submitRewardApplication")
    public RetResult submitRewardApplication(@RequestBody RewardSubmitDto rewardSubmitDto) {
//        Subject subject = SecurityUtils.getSubject();
//        LoginInfoDto loginInfoDto = (LoginInfoDto)subject.getPrincipal();
//        rewardSubmitDto.setUserId(loginInfoDto.getUserId());
//        int isSuccess = stuApplicationService.saveRewardRecord(rewardSubmitDto);
////        stuApplicationService.hhText(rewardSubmitDto);
//        if (isSuccess == 0) {
//            return RetResponse.makeRsp(RetCode.FAIL, "提交子类奖项记录失败");
//        }
//        return RetResponse.makeRsp(RetCode.SUCCESS, "成功提交子类奖项记录");

        //之前写了这个接口作为保存子类奖项接口的，结果ljk没用
        //结果在10/13的时候出问题了，我tm搞了半天，才发现我写过了，
        // 然后。。。。。在上面的/student2/saveRewardApplication接口改了半天
        // 不说了，心累
        //如果哪天来找我，我一定要骂他

        return RetResponse.makeRsp(RetCode.FAIL, "如果得到这串提示，找hh");
    }

    //获取某学生的子类奖项申请信息
    @ApiOperation("获取某学生的子类奖项申请信息")
    @GetMapping("/student2/getStuRewardApplication")
    public RetResult getStudentRewardApplication() {
        Subject subject = SecurityUtils.getSubject();
        LoginInfoDto loginInfoDto = (LoginInfoDto)subject.getPrincipal();
        StuRewardApplicationDto studentRewardRecord = null;
        try {
            studentRewardRecord = stuApplicationService.getStudentRewardRecord(loginInfoDto.getUserId());
        }
        catch (Exception e) {
            e.printStackTrace();
            logger.error("---userid: " + loginInfoDto.getUserId() + "---" + e.getMessage());
        }
//        stuApplicationService.hhText();

        return RetResponse.makeRsp(RetCode.SUCCESS, "获取学生奖学金申请信息成功", studentRewardRecord);
    }

    //获取学生奖学金申请提交状态
    @ApiOperation("获取学生奖学金申请提交状态")
    @GetMapping("/student2/getStuApplicationState")
    public RetResult getStuApplicationState() {
        Subject subject = SecurityUtils.getSubject();
        LoginInfoDto loginInfoDto = (LoginInfoDto)subject.getPrincipal();
        boolean allowSubmit = subject.hasRole("submit");
        StuStateInfoDto stuStateInfoDto = new StuStateInfoDto();
        Integer state = null;
        try {
            if (allowSubmit) {
                stuStateInfoDto.setRole(3);
            }
            else {
                stuStateInfoDto.setRole(1);
            }
            //此处原本是根据查询得到的state来设置stuStateInfoDto的state的
            //但由于逻辑改动，只要能查询得到state就表示存在申请记录
            state = stuApplicationService.getStuApplicationState(loginInfoDto.getUserId());
            stuStateInfoDto.setState(1);
        }
        catch (UserException e) {
//            e.printStackTrace();
            stuStateInfoDto.setState(0);
            logger.error("---userid: " + loginInfoDto.getUserId() + "---" + e.getMessage());
            return RetResponse.makeRsp(RetCode.SUCCESS, "该用户未提交奖学金申请信息", stuStateInfoDto);
        }
        catch (Exception e) {
            e.printStackTrace();
            logger.error("---userid: " + loginInfoDto.getUserId() + "---" + e.getMessage());
            return RetResponse.makeRsp(RetCode.FAIL, "未知错误");
        }
        return RetResponse.makeRsp(RetCode.SUCCESS, "获取学生奖学金申请提交状态成功", stuStateInfoDto);
    }

    //取消提交状态
    @ApiOperation("取消学生申请提交状态")
    @GetMapping("/student2/cancelStuApplication")
    public RetResult cancelStuApplication() {
        Subject subject = SecurityUtils.getSubject();
        LoginInfoDto loginInfoDto = (LoginInfoDto)subject.getPrincipal();
        try {
            stuApplicationService.cancelStuApplicationState(loginInfoDto.getUserId());
        }
        catch (UserException e) {
//            e.printStackTrace();
            logger.error("---userid: " + loginInfoDto.getUserId() + "---" + e.getMessage());
            return RetResponse.makeRsp(RetCode.FAIL, "该用户奖学金申请信息不存在", null);
        }
        catch (Exception e) {
            e.printStackTrace();
            logger.error("---userid: " + loginInfoDto.getUserId() + "---" + e.getMessage());
            return RetResponse.makeRsp(RetCode.FAIL, "未知错误");
        }
        return RetResponse.makeRsp(RetCode.SUCCESS, "取消学生申请提交状态成功", null);
    }

    //判断申请时间是否合理
    @ApiOperation("判断奖学金申请时间")
    @GetMapping("/student2/isAllowSubmit")
    public RetResult isAllowSubmit() {
        try {
            boolean isAllowSubmitApplication = stuApplicationService.checkSubmitTime();
            if (isAllowSubmitApplication == false) {
                return RetResponse.makeRsp(RetCode.SUCCESS, "当前时间不处于奖学金申请时间", false);
            }
        }
        catch (GetSQLException e) {
//            e.printStackTrace();
            logger.error(e.getMessage());
            return RetResponse.makeRsp(RetCode.FAIL, "获取奖学金申请时间范围失败，请稍后再试");
        }
        catch (Exception e) {
            e.printStackTrace();
            logger.error(e.getMessage());
            return RetResponse.makeRsp(RetCode.FAIL, "未知错误");
        }
        return RetResponse.makeRsp(RetCode.SUCCESS, "当前时间处于奖学金申请时间，允许提交", true);
    }

    /*------------------------------学生账户信息相关功能------------------------------*/

    //获取学生基本个人信息
    @ApiOperation("获取学生基本个人信息")
    @GetMapping("/student2/getStuBaseInfo")
    public RetResult getStuBaseInfo() {
        Subject subject = SecurityUtils.getSubject();
        LoginInfoDto loginInfoDto = (LoginInfoDto)subject.getPrincipal();
        StudentInfoDto studentInfo = null;
        try {
            studentInfo = studentService.getStudentInfo(loginInfoDto.getUserId());
        }
        catch (UserException e) {
//            e.printStackTrace();
            logger.error("---userid: " + loginInfoDto.getUserId() + " ---" + e.getMessage());
            return RetResponse.makeRsp(RetCode.FAIL, "该用户不存在，或个人信息有缺漏");
        }
        catch (Exception e) {
            e.printStackTrace();
            logger.error("---userid: " + loginInfoDto.getUserId() + " ---" + e.getMessage());
            return RetResponse.makeRsp(RetCode.FAIL, "未知错误");
        }
        logger.info("---userid: " + loginInfoDto.getUserId() + " --- 获取学生基本信息");
        return RetResponse.makeRsp(RetCode.SUCCESS, "学生基本信息", studentInfo);
    }

    //获取学生专业信息
    @ApiOperation("获取学生专业信息")
    @GetMapping("/student2/getStuMajorInfo")
    public RetResult getStuMajorInfo() {
        Subject subject = SecurityUtils.getSubject();
        LoginInfoDto loginInfoDto = (LoginInfoDto)subject.getPrincipal();
        MajorInfoDto majorInfoDto;
        try {
            majorInfoDto = studentService.getStudentMajorInfo(loginInfoDto.getUserId());
        }
        catch (UserException e) {
//            e.printStackTrace();
            logger.error("---userid: " + loginInfoDto.getUserId() + "---" + e.getMessage());
            return RetResponse.makeRsp(RetCode.FAIL, "该用户信息不存在");
        }
        catch (Exception e) {
            e.printStackTrace();
            logger.error("---userid: " + loginInfoDto.getUserId() + "---" + e.getMessage());
            return RetResponse.makeRsp(RetCode.FAIL, "未知错误");
        }
        return RetResponse.makeRsp(RetCode.SUCCESS, "获取学生专业信息成功", majorInfoDto);
    }

    //学生修改密码
    @ApiOperation("修改学生密码")
    @PostMapping("/student2/stuUpdatePwd")
    public RetResult stuUpdatePwd(@RequestBody StudentPasswordDto studentPassword) {
        Subject subject = SecurityUtils.getSubject();
        LoginInfoDto loginInfoDto = (LoginInfoDto)subject.getPrincipal();
        studentPassword.setUserId(loginInfoDto.getUserId());
        try {
            studentService.updateStudentPasswordInfo(studentPassword);
        }
        catch (PwdException e) {
//            e.printStackTrace();
            logger.error("---userid: " + loginInfoDto.getUserId() + "---" + e.getMessage());
            return RetResponse.makeRsp(RetCode.FAIL, "原密码错误");
        }
        catch (UpdateSQLException e) {
//            e.printStackTrace();
            logger.error("---userid: " + loginInfoDto.getUserId() + "---" + e.getMessage());
            return RetResponse.makeRsp(RetCode.FAIL, "数据库存储数据出错，稍后再试，或联系管理员");
        }
        catch (Exception e) {
            e.printStackTrace();
            logger.error("---userid: " + loginInfoDto.getUserId() + "---" + e.getMessage());
            return RetResponse.makeRsp(RetCode.FAIL, "未知错误");
        }
        return RetResponse.makeRsp(RetCode.SUCCESS, "修改学生密码成功");
    }

    //学生首次登入修改密码
    @ApiOperation("学生首次登入修改密码")
    @PostMapping("/student2/stuFirstLoginUpdatePwd")
    public RetResult stuFirstLoginUpdatePwd(@RequestParam("password") String password){
        Subject subject = SecurityUtils.getSubject();
        LoginInfoDto loginInfoDto = (LoginInfoDto)subject.getPrincipal();
        try {
            studentService.updateStudentPwdWhenFirstLogin(loginInfoDto.getUserId(), password);
        }
        catch (UserException e) {
//            e.printStackTrace();
            logger.error("---userid: " + loginInfoDto.getUserId() + "---" + e.getMessage());
            return RetResponse.makeRsp(RetCode.FAIL, "用户信息异常，稍后再试或联系管理员");
        }
        catch (UpdateSQLException e) {
//            e.printStackTrace();
            logger.error("---userid: " + loginInfoDto.getUserId() + "---" + e.getMessage());
            return RetResponse.makeRsp(RetCode.FAIL, "数据库存储数据出错，稍后再试，或联系管理员");
        }
        catch (Exception e) {
            e.printStackTrace();
            logger.error("---userid: " + loginInfoDto.getUserId() + "---" + e.getMessage());
            return RetResponse.makeRsp(RetCode.FAIL, "未知错误");
        }
        return RetResponse.makeRsp(RetCode.SUCCESS, "首次修改密码成功");
    }

    //学生修改基本信息
    @ApiOperation("修改学生基本信息")
    @PostMapping("/student2/stuUpdateBaseInfo")
    public RetResult stuUpdateBaseInfo(@RequestBody StudentChangeInfoDto stuInfo) {
        Subject subject = SecurityUtils.getSubject();
        LoginInfoDto loginInfoDto = (LoginInfoDto)subject.getPrincipal();
        try {
            stuInfo.setUserId(loginInfoDto.getUserId());
            studentService.updateStudentBaseInfo(stuInfo);
        }
        catch (GetSQLException e) {
            logger.error("---userid: " + loginInfoDto.getUserId() + "---" + e.getMessage());
            return RetResponse.makeRsp(RetCode.FAIL, "该邮箱已被使用");
        }
        catch (UpdateSQLException e) {
//            e.printStackTrace();
            logger.error("---userid: " + loginInfoDto.getUserId() + "---" + e.getMessage());
            return RetResponse.makeRsp(RetCode.FAIL, "数据库存储数据出错，请稍后再试或联系管理员");
        }
        catch (ErrorException e) {
            logger.error("---userid: " + loginInfoDto.getUserId() + "---" + e.getMessage());
            return RetResponse.makeRsp(RetCode.FAIL, "数据库存储数据出错，请联系管理员");
        }
        catch (Exception e) {
            e.printStackTrace();
            logger.error("---userid: " + loginInfoDto.getUserId() + "---" + e.getMessage());
            return RetResponse.makeRsp(RetCode.FAIL, "未知错误");
        }
        return RetResponse.makeRsp(RetCode.SUCCESS, "更新学生基本信息成功");
    }

    //检测学生首次登入
    @ApiOperation("检测学生首次登入")
    @GetMapping("/student2/checkIsFirstLogin")
    public RetResult checkIsFirstLogin() {
        Subject subject = SecurityUtils.getSubject();
        LoginInfoDto loginInfoDto = (LoginInfoDto)subject.getPrincipal();
        try {
            Boolean isFirstLogin = studentService.isFirstLogin(loginInfoDto.getUserId());
            if (isFirstLogin == false) {
                return RetResponse.makeRsp(RetCode.SUCCESS, "检测学生首次登入成功", false);
            }
        }
        catch (Exception e) {
            e.printStackTrace();
            logger.error("---userid: " + loginInfoDto.getUserId() + "---" + e.getMessage());
            //TODO 10/29 这里写成了RetCode.SUCCESS，忘了是不是自己特意写的，以后回来看看，否则改成FALL
            return RetResponse.makeRsp(RetCode.SUCCESS, "未知错误");
        }
        return RetResponse.makeRsp(RetCode.SUCCESS, "检测学生首次登入成功", true);
    }

    //提供规则文件的下载网址
    @ApiOperation("获取规则文件的下载网址")
    @GetMapping("/student2/getRuleFiles")
    public RetResult getRuleFiles() {
        return RetResponse.makeRsp(RetCode.SUCCESS, "获取规则文件的下载网址", "https://cdn.zhz1314.cn/reward/2021_9/c1a518b1-fa45-4be7-81fe-d0c972d96a87信息技术学院专业奖学金及荣誉称号评选规则(适用于2021年10月评比).rar");
    }

    @ApiOperation("根据学号获取学生总分 @author zhz")
    @GetMapping("/student2/getStuTotalScore")
    public RetResult getStuTotalScoreById(){
        Subject subject = SecurityUtils.getSubject();
        LoginInfoDto loginInfoDto = (LoginInfoDto)subject.getPrincipal();
        return RetResponse.makeRsp(RetCode.SUCCESS,"分数查询成功",stuTotalScoreService.getStuTotalScoreById(loginInfoDto.getUserId()));
    }
}
